package cn.wp.ewallet.wallet.service.impl;

import cn.wp.common.core.id.Id;
import cn.wp.ewallet.common.extension.properties.EthProperties;
import cn.wp.ewallet.wallet.extension.constant.EwalletWalletConstant;
import cn.wp.ewallet.wallet.extension.util.EwalleTransactionUtil;
import cn.wp.ewallet.wallet.model.dto.TransAccountLogDto;
import cn.wp.ewallet.wallet.service.AccountInfoService;
import cn.wp.ewallet.wallet.service.TransAccountLogService;
import cn.wp.ewallet.wallet.service.WebTransferService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.concurrent.ExecutionException;

/**
 * 区块链转账交易服务
 * Created by zhangyongli on 2020/2/6
 */

@Slf4j
@Service
public class WebTransferServiceImpl implements WebTransferService {

    @Autowired
    private TransAccountLogService transAccountLogService;

    @Autowired
    private AccountInfoService accountInfoService;

    @Autowired
    private EthProperties ethProperties;

    @Override
    public Boolean webTransferFromCenter(String toAddress, BigInteger tokenBlance, String contractAddress, String moneyTypeId, String reqOrderId, String remark) {

        EwalleTransactionUtil walleUtil = EwalleTransactionUtil.getInstance();
        //连接web3j
        Web3j web3j = walleUtil.getDefaultConect(ethProperties.getNetwork());

        log.info("转入地址={}", toAddress);
        try {

            //生成证书
            Credentials credentials = Credentials.create(ethProperties.getPrivateKey());
            //执行转账
            String txHash= walleUtil.transferERC20Token(web3j, ethProperties.getCentralAddress(), toAddress, tokenBlance, credentials, contractAddress);

            if (StringUtils.isEmpty(txHash)) {
                log.error("中央地址转出失败，转入地址={}", toAddress);
                return false;
            }
            //记录转账交易
            saveTransferInfo(txHash, ethProperties.getCentralAddress(), toAddress, tokenBlance, moneyTypeId, EwalletWalletConstant.TRANS_LOG_TYPE_MENTION_MONEY, reqOrderId, remark);

            log.info("转入地址={}, 转账完成", toAddress);
            return true;

        } catch (IOException e) {
            log.error("转账失败，转入地址={}， msg={}", toAddress, e.getMessage());
            e.printStackTrace();
        } catch (InterruptedException e) {
            log.error("转账失败，转入地址={}， msg={}", toAddress, e.getMessage());
            e.printStackTrace();
        } catch (ExecutionException e) {
            log.error("转账失败，转入地址={}， msg={}", toAddress, e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            log.error("转账失败，转入地址={}， msg={}", toAddress, e.getMessage());
            e.printStackTrace();
        }

        return false;
    }

    /**
     * 记录转账记录
     * @param txHash
     * @param fromAddress
     * @param toAddress
     * @param tokenBlance
     */
    private void saveTransferInfo(String txHash, String fromAddress, String toAddress, BigInteger tokenBlance, String moenyTypeId, String operType, String reqOrderId, String remark) {
        //记录转账记录,自动归集时，手续费无法准确计算，总共费用是两种币，不能相加, 记录手续为0，后续更新
        TransAccountLogDto transAccountLogDto = new TransAccountLogDto(Id.gen(), fromAddress, toAddress, new Date(),
                BigDecimal.valueOf(tokenBlance.doubleValue()), BigDecimal.valueOf(0), BigDecimal.valueOf(tokenBlance.doubleValue()),
                EwalletWalletConstant.TRANSFER_OPER_RESULT_WAITING, "system", remark, moenyTypeId, txHash);
        transAccountLogDto.setOperType(operType);
        transAccountLogDto.setReqOrderId(reqOrderId);

        transAccountLogService.saveTransAccountLog(transAccountLogDto);
    }

}
